<template>
    <div class="image-viewer-container">
      <!-- 图片列表展示区域 -->
      <div class="image-grid" v-if="showGrid">
        <div 
          v-for="(image, index) in images" 
          :key="index" 
          class="image-item"
          @click="openViewer(index)"
        >
          <img 
            :src="image.src || image" 
            :alt="image.alt || `Image ${index + 1}`" 
            :title="image.title || ''"
            @error="handleImageError($event, index)"
            class="thumbnail"
          />
        </div>
      </div>
  
      <!-- 自定义插槽内容 -->
      <div v-else>
        <slot name="image-content"></slot>
      </div>
  
      <!-- 图片预览弹窗 -->
      <transition name="viewer-fade">
        <div v-if="isViewerOpen" class="viewer-overlay" @click="closeViewer">
          <div class="viewer-container" @click.stop>
            <!-- 关闭按钮 -->
            <button class="viewer-close" @click="closeViewer">×</button>
            
            <!-- 图片显示区域 -->
            <div class="viewer-content">
              <img 
                ref="viewerImage" 
                :src="currentImage.src || currentImage" 
                :alt="currentImage.alt || 'Preview Image'"
                class="viewer-image"
              />
            </div>
            
            <!-- 导航按钮 -->
            <button 
              class="viewer-nav viewer-prev" 
              @click="prevImage"
              :disabled="currentIndex <= 0"
            >
              ‹
            </button>
            <button 
              class="viewer-nav viewer-next" 
              @click="nextImage"
              :disabled="currentIndex >= images.length - 1"
            >
              ›
            </button>
            
            <!-- 图片计数器 -->
            <div class="viewer-counter">
              {{ currentIndex + 1 }} / {{ images.length }}
            </div>
            
            <!-- 操作按钮 -->
            <div class="viewer-actions">
              <button class="action-btn" @click="zoomIn">
                <i class="el-icon-zoom-in"></i>
              </button>
              <button class="action-btn" @click="zoomOut">
                <i class="el-icon-zoom-out"></i>
              </button>
              <button class="action-btn" @click="resetZoom">
                <i class="el-icon-refresh"></i>
              </button>
              <button class="action-btn" @click="downloadImage">
                <i class="el-icon-download"></i>
              </button>
            </div>
          </div>
        </div>
      </transition>
    </div>
  </template>
  
  <script>
  export default {
    name: 'ImageViewer',
    props: {
      // 图片数组，可以是字符串数组或对象数组
      images: {
        type: Array,
        required: true,
        default: () => []
      },
      // 是否显示网格布局
      showGrid: {
        type: Boolean,
        default: true
      },
      // 默认图片（加载失败时显示）
      placeholderImage: {
        type: String,
        default: 'https://via.placeholder.com/200x200?text=Image+Not+Found'
      },
      // 初始缩放比例
      initialZoom: {
        type: Number,
        default: 1
      }
    },
    data() {
      return {
        isViewerOpen: false,
        currentIndex: 0,
        currentZoom: this.initialZoom,
        scaleStep: 0.1
      }
    },
    computed: {
      // 当前显示的图片
      currentImage() {
        return this.images[this.currentIndex] || {};
      }
    },
    methods: {
      // 打开图片预览
      openViewer(index) {
        this.currentIndex = index;
        this.currentZoom = this.initialZoom;
        this.isViewerOpen = true;
        
        // 阻止页面滚动
        document.body.style.overflow = 'hidden';
        
        // 监听键盘事件
        document.addEventListener('keydown', this.handleKeyDown);
      },
      
      // 关闭图片预览
      closeViewer() {
        this.isViewerOpen = false;
        
        // 恢复页面滚动
        document.body.style.overflow = 'auto';
        
        // 移除键盘事件监听
        document.removeEventListener('keydown', this.handleKeyDown);
      },
      
      // 上一张图片
      prevImage() {
        if (this.currentIndex > 0) {
          this.currentIndex--;
          this.currentZoom = this.initialZoom;
        }
      },
      
      // 下一张图片
      nextImage() {
        if (this.currentIndex < this.images.length - 1) {
          this.currentIndex++;
          this.currentZoom = this.initialZoom;
        }
      },
      
      // 放大图片
      zoomIn() {
        this.currentZoom += this.scaleStep;
        this.updateImageTransform();
      },
      
      // 缩小图片
      zoomOut() {
        if (this.currentZoom > this.scaleStep) {
          this.currentZoom -= this.scaleStep;
          this.updateImageTransform();
        }
      },
      
      // 重置缩放
      resetZoom() {
        this.currentZoom = this.initialZoom;
        this.updateImageTransform();
      },
      
      // 更新图片变换
      updateImageTransform() {
        if (this.$refs.viewerImage) {
          this.$refs.viewerImage.style.transform = `scale(${this.currentZoom})`;
        }
      },
      
      // 下载图片
      downloadImage() {
        const imageSrc = this.currentImage.src || this.currentImage;
        const link = document.createElement('a');
        link.href = imageSrc;
        link.download = `image_${Date.now()}.jpg`;
        link.click();
      },
      
      // 处理图片加载失败
      handleImageError(event, index) {
        event.target.src = this.placeholderImage;
      },
      
      // 处理键盘事件
      handleKeyDown(event) {
        switch (event.key) {
          case 'Escape':
            this.closeViewer();
            break;
          case 'ArrowLeft':
            this.prevImage();
            break;
          case 'ArrowRight':
            this.nextImage();
            break;
          case '+':
          case '=':
            if (!event.shiftKey) {
              this.zoomIn();
            }
            break;
          case '-':
            this.zoomOut();
            break;
          case '0':
            this.resetZoom();
            break;
        }
      }
    },
    // 监听当前图片变化，重置缩放
    watch: {
      currentImage() {
        this.$nextTick(() => {
          this.updateImageTransform();
        });
      }
    },
    // 组件销毁时清理
    beforeDestroy() {
      document.body.style.overflow = 'auto';
      document.removeEventListener('keydown', this.handleKeyDown);
    }
  }
  </script>
  
  <style scoped lang="scss">
  .image-viewer-container {
    width: 100%;
  }
  
  // 图片网格布局样式
  .image-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 10px;
  }
  
  .image-item {
    cursor: pointer;
    overflow: hidden;
    border-radius: 4px;
    transition: transform 0.2s, box-shadow 0.2s;
    position: relative;
    height: 150px;
  
    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    }
  
    .thumbnail {
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 0.3s;
  
      &:hover {
        transform: scale(1.05);
      }
    }
  }
  
  // 图片预览弹窗样式
  .viewer-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.9);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
    cursor: zoom-out;
  }
  
  .viewer-container {
    position: relative;
    width: 90%;
    height: 90%;
    cursor: default;
  }
  
  .viewer-close {
    position: absolute;
    top: -40px;
    right: 0;
    width: 36px;
    height: 36px;
    border: none;
    background-color: rgba(255, 255, 255, 0.2);
    color: white;
    font-size: 24px;
    border-radius: 50%;
    cursor: pointer;
    transition: background-color 0.2s;
  
    &:hover {
      background-color: rgba(255, 255, 255, 0.3);
    }
  }
  
  .viewer-content {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
  }
  
  .viewer-image {
    max-width: 100%;
    max-height: 100%;
    transition: transform 0.2s ease;
  }
  
  .viewer-nav {
    position: absolute;
    top: 50%;
    width: 48px;
    height: 48px;
    border: none;
    background-color: rgba(255, 255, 255, 0.2);
    color: white;
    font-size: 24px;
    border-radius: 50%;
    cursor: pointer;
    transform: translateY(-50%);
    transition: background-color 0.2s;
  
    &:hover:not(:disabled) {
      background-color: rgba(255, 255, 255, 0.3);
    }
  
    &:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
  }
  
  .viewer-prev {
    left: -24px;
  }
  
  .viewer-next {
    right: -24px;
  }
  
  .viewer-counter {
    position: absolute;
    bottom: -30px;
    left: 50%;
    transform: translateX(-50%);
    color: white;
    background-color: rgba(0, 0, 0, 0.5);
    padding: 4px 8px;
    border-radius: 12px;
    font-size: 14px;
  }
  
  .viewer-actions {
    position: absolute;
    bottom: -40px;
    right: 0;
    display: flex;
    gap: 8px;
  }
  
  .action-btn {
    width: 32px;
    height: 32px;
    border: none;
    background-color: rgba(255, 255, 255, 0.2);
    color: white;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.2s;
  
    &:hover {
      background-color: rgba(255, 255, 255, 0.3);
    }
  }
  
  // 过渡动画
  .viewer-fade-enter-active,
  .viewer-fade-leave-active {
    transition: opacity 0.3s;
  }
  
  .viewer-fade-enter,
  .viewer-fade-leave-to {
    opacity: 0;
  }
  
  // 响应式调整
  @media (max-width: 768px) {
    .image-grid {
      grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
      gap: 8px;
    }
  
    .image-item {
      height: 100px;
    }
  
    .viewer-container {
      width: 95%;
      height: 85%;
    }
  
    .viewer-nav {
      width: 40px;
      height: 40px;
      font-size: 20px;
    }
  
    .viewer-prev {
      left: -20px;
    }
  
    .viewer-next {
      right: -20px;
    }
  
    .viewer-actions {
      bottom: -35px;
    }
  
    .action-btn {
      width: 28px;
      height: 28px;
      font-size: 14px;
    }
  }
  </style>